﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignPatterns.BuilderPatterns
{
    /// <summary>
    /// 工厂模式注重创造不同产品
    /// 建造者模式注重创造同一产品的不同型号
    /// </summary>
    class BuilderPattern
    {
        static void Main(string[] args)
        {
            //实例化导演
            Director dir = new Director();
            //生产产品的A型号
            var producta = dir.getAProduct();
            //生产产品的B型号
            var productb = dir.getBProduct();

            Console.Read();
        }
    }

    /// <summary>
    /// 产品
    /// </summary>
    public class Product {
        public List<int> steps { get; set; }
        private void action1() { }
        private void action2() { }
        private void action3() { }
        /// <summary>
        /// 独立业务
        /// </summary>
        public void doSomething() {
            if (steps != null)
                foreach (var item in steps) {
                    if (item == 1)
                        action1();
                    else if (item == 2)
                        action2();
                    else if (item == 3)
                        action3();
                }
        }
    }

    /// <summary>
    /// 抽象建造者
    /// </summary>
    public abstract class Builder {
        /// <summary>
        /// 设置不同产品的不同零部件，用以生产不同的产品
        /// </summary>
        public abstract void setPart();
        public abstract Product buildProduct();
    }

    /// <summary>
    /// 具体建造者1
    /// 同一产品，如果出了细节不同的新型号，可以扩展新的具体建造者
    /// 具体建造者之间互相独立，模块之间互不影响，扩展成本极低
    /// </summary>
    public class ConcreteProduct1 : Builder
    {
        private Product product = new Product();
        public override Product buildProduct()
        {
            return product;
        }

        public override void setPart()
        {
            product.steps = new List<int>() { 1,2,3,1,2,1};
        }
    }

    /// <summary>
    /// 具体建造者2
    /// </summary>
    public class ConcreteProduct2 : Builder
    {
        private Product product = new Product();
        public override Product buildProduct()
        {
            return product;
        }

        public override void setPart()
        {
            product.steps = new List<int>() { 3, 2, 3 };
        }
    }

    /// <summary>
    /// 导演，负责整合所有建造者
    /// 如果项目庞大，多个导演也可以
    /// </summary>
    public class Director {
        private Builder builder1 = new ConcreteProduct1();
        public Product getAProduct() {
            builder1.setPart();
            return builder1.buildProduct();
        }
        private Builder builder2 = new ConcreteProduct2();
        public Product getBProduct()
        {
            builder2.setPart();
            return builder2.buildProduct();
        }
    }
}
